home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / telecom / 119 / c / apskel2.c next >
Encoding:
C/C++ Source or Header  |  1987-04-16  |  24.4 KB  |  768 lines

  1. /*********************************************************************/
  2. /*                    Application Skeleton #2 
  3.     
  4.     This program began as an experiment with GEM programming.  Starting
  5.     with the "APSKEL.C" supplied with the developers kit, I reorganized 
  6.     code for readability, fixed bugs, added new featues and learned 
  7.     about some GEM idiosyncrasys. The resulted is a collection of functions 
  8.     that should prove useful to beginning GEM programmers.  I know 
  9.     these examples would have save me a lot of time.  Keep in mind that 
  10.     GEM programming is not simple - it requires a lot of perseverance.
  11.     Note, the window color feature is not completed.
  12.     
  13. */                                                 
  14. /*********************************************************************/
  15. /* INCLUDE FILES                             */
  16. /*********************************************************************/
  17.  
  18. #include <obdefs.h>
  19. #include <define.h>
  20. #include <gemdefs.h>
  21. #include <osbind.h>
  22. #include <string.h>
  23.  
  24. /*********************************************************************/
  25. /* DEFINES                                    */
  26. /*********************************************************************/
  27. /*  Header file created by the resource construction program 
  28.  
  29.         Naming Conventions:  _T  =  object tree
  30.                              _O  =  object
  31.                              _M  =  menu point
  32.                              _E  =  menu entry
  33.                              _B  =  button 
  34. */
  35. #define MENU_T 0
  36. #define DESK_M 3
  37. #define FILE_M 4
  38. #define SHOW_M 5
  39. #define HELP_M 7
  40. #define OPTION_M 6
  41. #define ABOUT_E 10
  42. #define ABOUT_T 1
  43. #define OPEN_E 19
  44. #define CLOSE_E 20
  45. #define ABOUT_B 9
  46. #define QUIT_E 22
  47. #define WINFO_E 24
  48. #define SOLFIL_E 27
  49. #define DOTFIL_E 26
  50. #define CRSFIL_E 28
  51. #define TRACE_E 30
  52. #define HWIND_E 32
  53. #define HARSLD_E 33
  54. #define HTRACE_E 34
  55. #define TRACE_T 5
  56. #define WINDOW_T 3
  57. #define WINDOW_B 7
  58. #define WINFO_T 4
  59. #define X_O 6
  60. #define WIDTH_O 9
  61. #define Y_O 11
  62. #define ARSLID_T 2
  63. #define STYLE_O 13
  64. #define INTER_O 17
  65. #define COLOR_O 16
  66. #define HEIGTH_O 18
  67. #define WINFO_B 19
  68. #define WINDNB_O 14
  69. #define ARSLID_B 11
  70.  
  71. #define WI_KIND    (SIZER|MOVER|FULLER|CLOSER|NAME|UPARROW|DNARROW|VSLIDE|LFARROW|RTARROW|HSLIDE)
  72. #define NO_WINDOW (-1)
  73. #define MIN_WIDTH  (2*gl_wbox)
  74. #define MIN_HEIGHT (3*gl_hbox)
  75.  
  76. /*   Resource File Info       */
  77. #define RSCF_NAME "APSKEL2.RSC"
  78. #define RSCNOTFND "[3][ Resource File | 'APSKEL2.RSC' |   Not Found ][ EXIT ]"
  79. #define RSCBAD    "[3][ Resource File | 'APSKEL2.RSC' | Is Corrupted ][ EXIT ]"
  80. #define TOMANY_WI "[3][ Too Many Windows Open ][ OK ]"
  81.  
  82. #define WI_MAX    8                /* maximum number of windows */
  83. /*********************************************************************/
  84. /* EXTERNALS                                    */
  85. /*********************************************************************/
  86.  
  87. extern int    gl_apid;
  88.  
  89. /*********************************************************************/
  90. /* GLOBAL VARIABLES                                */
  91. /*********************************************************************/
  92. int    contrl[12];                    /* GEM control arrays  */
  93. int    intin[128];
  94. int    ptsin[128];
  95. int    intout[128];
  96. int    ptsout[128];
  97.  
  98. int    gl_hchar;
  99. int    gl_wchar;
  100. int    gl_wbox;
  101. int    gl_hbox;                    /* system sizes */
  102.  
  103. int ap_id;                        /* application ID  */
  104. int phys_handle;                /* physical workstation handle */
  105. int v_handle;                    /* virtual workstation handle */
  106.  
  107. OBJECT *menutree;                /* menu tree address  */
  108.  
  109. struct wi_control {                /* WINDOW CONTROL STRUCTURE */
  110.     int handle;                    /* window handle */
  111.     int style;                    /* style index */
  112.     int color;                    /* color index */
  113.     int inter;                    /* interior index */
  114.     int x;                        /* initial x coordinate */
  115.     int y;                        /* initial y coordinate */
  116.     int w;                        /* initial width */
  117.     int h;                        /* initial height */
  118.     char name[30];                /* window name */
  119. } wi_c[WI_MAX];
  120.  
  121. int wi_nbr=0;                    /* number of windows open */
  122. int    xdesk,ydesk,hdesk,wdesk;    /* desktop coordinates */
  123.  
  124. int terminat=FALSE;                /* terminat flag  */
  125. int dtrace=FALSE;                /* debug trace flag     */
  126. int    msgbuff[8];                    /* event message buffer */
  127. int    fulled;                        /* current state of window */
  128. int re_draw;                    /* redraw top window flag*/
  129. int hidden;                        /* current state of cursor */
  130. int keycode;                    /* keycode ret. by event-keyboard */
  131. int butdown;                    /* button state tested for, UP/DOWN */
  132. int mx, my;                        /* mouse x and y pos. */
  133.  
  134. int work_in[11];                /* Input to GSX parameter array */
  135. int work_out[57];                /* Output from GSX parameter array */
  136. int pxyarray[10];                /* input point array */
  137.  
  138. /****************************************************************/
  139. /*                                                                */
  140. /*                              M A I N                                */
  141. /*                                                                */
  142. /****************************************************************/
  143. main()
  144. {
  145.     start_applic();                /* start application  */
  146.     init_wctl();                /* initialize window ctl array */
  147.     get_rscfile();                /* get resource file  */
  148.     show_menubar();                /* show menu bar      */
  149.     proc_events();                /* process GEM events */
  150.     end_applic();                /* Wrap-up GEM        */
  151.     exit(0);                    /* return (no error)  */
  152. }
  153. /*                                                                */
  154. /****************************************************************/
  155. /*  start application                       */
  156. /****************************************************************/
  157. start_applic()
  158. {
  159.     int i;
  160.     ap_id=appl_init();
  161.     phys_handle=graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox);
  162.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  163.         /* Open Virtual Workstation    */
  164.     for(i=0;i<10;work_in[i++]=1);
  165.     work_in[10]=2;
  166.     v_handle=phys_handle;
  167.     v_opnvwk(work_in,&v_handle,work_out);
  168. }
  169. /****************************************************************/
  170. /*  end application                         */
  171. /****************************************************************/
  172. end_applic()
  173. {
  174.     int i, wh;
  175.     debug_alert("gem_wrap", "CLOSE OPEN WIND/REMOV MENU", 0);
  176.     for(i=0; i<WI_MAX; i++) {        /* close any open windows */
  177.         wh=wi_c[i].handle; 
  178.         if(wh) {
  179.             wind_close(wh);
  180.             wind_delete(wh);
  181.         }
  182.     }
  183.     menu_bar(menutree, FALSE);        /* remove menu bar */
  184.     v_clsvwk(v_handle);                /* close virtual work station */
  185.     appl_exit();                    /* tell GEM we are done */
  186. }
  187. /****************************************************************/
  188. /*   Initialize Window Control Array   */
  189. /****************************************************************/
  190. init_wctl()
  191. {            /*  set default values for windows  */
  192.     int i;
  193.     for(i=0; i<WI_MAX; i++) {
  194.         wi_c[i].handle=0;                    /* clear handle */
  195.         wi_c[i].style=1+(2*i);                /* pattern */
  196.         wi_c[i].color=1;                    /* color */
  197.         wi_c[i].inter=2;                    /* interior */
  198.         wi_c[i].x=xdesk+(20*i+1);            /* location */
  199.         wi_c[i].y=ydesk+(16*i+1);
  200.         wi_c[i].w=wdesk-130;                /* size */
  201.         wi_c[i].h=hdesk-110;
  202.     }
  203. }
  204. /****************************************************************/
  205. /*  get the resource file  */
  206. /****************************************************************/
  207. get_rscfile()
  208. {
  209.     if(!rsrc_load(RSCF_NAME)) {        /* load resource file */
  210.         form_alert(1, RSCNOTFND);    /* error - file not found, use ALERT */
  211.         end_applic();                /* end application & exit */
  212.         exit(1);
  213.     }
  214. }
  215. /***************************************************************/
  216. /*  show menu bar    */
  217. /***************************************************************/
  218. show_menubar()
  219. {                    /* get address of menu tree */
  220.     if(!rsrc_gaddr(R_TREE, MENU_T, &menutree)) {    
  221.         form_alert(1, RSCBAD);                /* bad rsc file */
  222.         end_applic();
  223.         exit(1);
  224.     }
  225.     menu_bar(menutree, TRUE);                /* display menu bar */
  226. }
  227. /****************************************************************/
  228. /*  open window                            */
  229. /****************************************************************/
  230. open_window()
  231. {
  232.     int wh, i, x, y, w, h;
  233.     char s[25];
  234.     wh=wind_create(WI_KIND, xdesk, ydesk, wdesk, hdesk);
  235.     if(wh < 0) return(wh);        /* too many windows open */
  236.     i=wi_geti(0);
  237.     debug_alert("open_window", "OPEN A WINDOW", i+1);
  238.     wi_c[i].handle=wh;            /* save handle */
  239.     x=wi_c[i].x;                /* get initial window size */
  240.     y=wi_c[i].y;
  241.     w=wi_c[i].w;
  242.     h=wi_c[i].h;
  243.     strcpy(s, " Window #");        /*  create window name  */
  244.     itoa(i+1, s+9, 1);
  245.     strcat(s, "           ");
  246.     strcpy(wi_c[i].name, s);    
  247.     disp_loc(wh, x, y);
  248.                                 /*  set name & display window  */
  249.     wind_set(wh, WF_NAME, wi_c[i].name, 0, 0);
  250.     graf_growbox(x+w/2, y+h/2, gl_wbox, gl_hbox, x, y, w, h);
  251.     wind_open(wh, x, y, w, h);
  252.     wi_nbr++;
  253.     return(wh);                    /* return handle */
  254. }
  255. /****************************************************************/
  256. /*  display window location */
  257. /****************************************************************/
  258. disp_loc(wh, x, y)
  259. int wh, x, y;
  260. {
  261.     int i;
  262.     char s[25];
  263.     i=wi_geti(wh);
  264.     itoa(x, s, 3);                    /* make x & y string */
  265.     itoa(y, s+4, 3);
  266.     s[3]=' ';
  267.     strcpy(&wi_c[i].name[12], s);    /* and move to control array */
  268. }    
  269. /****************************************************************/
  270. /* close window                          */
  271. /***************************************************************/
  272. close_window(wh)
  273. int wh;
  274. {
  275.     int i, x, y, w, h;
  276.     wind_get(wh, WF_CURRXYWH, &x, &y, &w, &h);
  277.     i=wi_geti(wh);
  278.     debug_alert("close_window", "CLOSE A WINDOW", i+1);
  279.     wind_close(wh);
  280.     graf_shrinkbox(x+w/2, y+h/2, gl_wbox, gl_hbox, x, y, w, h);
  281.     wind_delete(wh);
  282.     wi_c[wi_geti(wh)].handle=0;
  283.     wi_nbr--;
  284. }
  285. /****************************************************************/
  286. /*   Get Window Control Index   */
  287. /****************************************************************/
  288. wi_geti(wh)
  289. int wh;
  290. {    /* find the control index that matches the window handle */
  291.     int i;
  292.     for(i=0; i<WI_MAX && wi_c[i].handle!=wh; i++);
  293.     return(i);
  294. }
  295. /**************************************************************/
  296. /*   Debug Display    */
  297. /**************************************************************/
  298. debug_alert(s1, s2, n)
  299. int n;                /* create debug alert box from two strings s1 and s2 , */
  300. char *s1, *s2;        /* and the integer n */
  301. {
  302.     char s3[110];
  303.     if(dtrace == FALSE) return;
  304.     strcpy(s3, "[3][ ");
  305.     strcat(s3, s1);            
  306.     strcat(s3, " | | ");
  307.     strcat(s3, s2);
  308.     strcat(s3, " |      ");
  309.     itoa(n, s3+strlen(s3)-1, 6);
  310.     strcat(s3, " |  ][ GO ]");
  311.     form_alert(1, s3);
  312. }
  313. /**************************************************************/
  314. /*   Integer to Ascii      */
  315. /**************************************************************/
  316. itoa(n1, s, n2)    /* convert n1 to characters in s with minimum */
  317. int n1, n2;        /* length n2 */
  318. char s[];
  319. {
  320.     int i, sign;
  321.     if((sign=n1) < 0)            /* record sign */
  322.         n1 = -n1;                /* make n positive */
  323.     i = 0;
  324.     do {                        /* generate digits in reverse order */
  325.         s[i++]=n1 % 10 + '0';    /* get next digit */
  326.     }
  327.     while((n1 /= 10) > 0);        /* delete it */
  328.     while(i < n2) s[i++] = '0';
  329.     if(sign < 0) s[i++] = '-';
  330.     s[i] = '\0';
  331.     reverse(s);
  332. }
  333. reverse(s)    /* reverse string s in place */
  334. char s[];
  335. {
  336.     int c, i, j;
  337.     for(i=0, j=strlen(s)-1; i< j; i++, j--) {
  338.         c=s[i];
  339.         s[i]=s[j];
  340.         s[j]=c;
  341.     }
  342. }
  343. /****************************************************************/
  344. /*  GSX UTILITY ROUTINES.                    */
  345. /****************************************************************/
  346. hide_mouse()
  347. {
  348.     if(! hidden){
  349.         graf_mouse(M_OFF,0x0L);
  350.         hidden=TRUE;
  351.     }
  352. }
  353. show_mouse()
  354. {
  355.     if(hidden){
  356.         graf_mouse(M_ON,0x0L);
  357.         hidden=FALSE;
  358.     }
  359. }
  360. /****************************************************************/
  361. /*  Check if Window is Smaller              */
  362. /****************************************************************/
  363. wind_smaller(wh)
  364. int wh;
  365. {    /* is resized window smaller than its previous size ?*/
  366.     /* this check is necessary because GEM does not send */
  367.     /* redraw event message in this case */
  368.     int px, py, pw, ph, x, y, w, h;
  369.     wind_get(wh, WF_CURRXYWH, &x, &y, &w, &h);
  370.     wind_get(wh, WF_PREVXYWH, &px, &py, &pw, &ph);
  371.     if(w < pw && h < ph) return(1);
  372.     return(0);
  373. }
  374. /****************************************************************/
  375. /*   Draw Dialog Box
  376. /****************************************************************/
  377. draw_dbox(ti, ta)
  378. int ti;                                    /* tree index */
  379. long int *ta;                            /* tree address */                                
  380. {
  381.     int x, y, w, h;
  382.     debug_alert("draw_dbox", "DRAW DIALOG BOX", 0);
  383.     rsrc_gaddr(R_TREE, ti, ta);            /* get address of tree */
  384.     form_center(*ta, &x, &y, &w, &h);    /* get loc of centered tree */
  385.         /* reserve memory for dialog box */
  386.     form_dial(FMD_START, x, y, w, h, 0,0,0,0); /* you need those zeros */
  387.         /* draw growing box */
  388.     form_dial(FMD_GROW, x+w/2, y+h/2, gl_wbox, gl_hbox, x, y, w, h);
  389.         /* draw object tree */
  390.     objc_draw(*ta, ROOT, MAX_DEPTH, x, y, w, h);
  391. }
  392. /****************************************************************/
  393. /*   Erase Dialog Box    */
  394. /****************************************************************/
  395. erase_dbox(ti)
  396. int ti;                                    /* tree index */
  397. {
  398.     int x, y, w, h;
  399.     OBJECT *ta;
  400.     debug_alert("erase_dbox", "ERASE DIALOG BOX", 0);
  401.     rsrc_gaddr(R_TREE, ti, &ta);        /* get address of tree */
  402.     form_center(ta, &x, &y, &w, &h);    /* get loc of centered tree */
  403.         /* release memory used by dialog box */
  404.     form_dial(FMD_FINISH, 0, 0, 0, 0, x, y, w, h);
  405.         /* draw shrinking box */
  406.     form_dial(FMD_SHRINK, x+w/2, y+h/2, gl_wbox, gl_hbox, x, y, w, h);
  407. }
  408. /****************************************************************/
  409. /*   Simple Dialog     */
  410. /****************************************************************/
  411. simple_dialog(ti)
  412. int ti;                /* draw dialog box, wait for user to exit, */
  413. {                    /* then erase dialog box */
  414.     OBJECT *ta;
  415.     debug_alert("simple_dialog", "DRAW BOX/WAIT FOR EXIT/ERASE", 0); 
  416.     draw_dbox(ti, &ta);
  417.     form_do(ta, 0);    /* dialog boxes were created with touch exit buttons */
  418.     erase_dbox(ti);
  419. }
  420. /****************************************************************/
  421. /*   Set Clipping Rectangle                    */
  422. /****************************************************************/
  423. set_clip(x, y, w, h)
  424. int x, y, w, h;
  425. {
  426.     int clip[4];
  427.     clip[0]=x;
  428.     clip[1]=y;
  429.     clip[2]=x+w-1;            /* the -1 was not in the ATARI example */
  430.     clip[3]=y+h-1;
  431.     vs_clip(v_handle, 1, clip);
  432. }
  433. /****************************************************************/
  434. /*   Find and Redraw All Clipping Rectangles            */
  435. /****************************************************************/
  436. do_redraw(wh, xc, yc, wc, hc)
  437. int wh, xc, yc, wc, hc;
  438. {
  439.     GRECT t1, t2;
  440.     int i, x, y, w, h;
  441.     i=wi_geti(wh);
  442.     if(wh == 0) return;        /* no windows open */
  443.     debug_alert("do_redraw", "FIND/REDRAW CLIPPING RECTANGLES", i+1); 
  444.     hide_mouse();
  445.     wind_update(TRUE);
  446.     t2.g_x=xc;
  447.     t2.g_y=yc;
  448.     t2.g_w=wc;
  449.     t2.g_h=hc;
  450.     wind_get(wh, WF_WORKXYWH, &x, &y, &w, &h);
  451.     wind_get(wh, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  452.     while (t1.g_w && t1.g_h) {
  453.         if (rc_intersect(&t2, &t1)) {
  454.             set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  455.             draw_ellipse(wi_c[i].inter, wi_c[i].style, 
  456.                 i+1, x, y, w, h);
  457.         }
  458.         wind_get(wh, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  459.     }
  460.     wind_update(FALSE);
  461.     show_mouse();
  462. }
  463. /****************************************************************/
  464. /* Draw Filled Ellipse.                        */
  465. /****************************************************************/
  466. draw_ellipse(in, sty, col, x, y, w, h)
  467. int in, sty, col, x, y, w, h;
  468. {
  469.     int temp[4];
  470.     debug_alert("draw_ellipse", "DRAW ELLIPSE IN LOC SPECIFIED", 0); 
  471.     vsf_interior(v_handle, 1);
  472.     vsf_color(v_handle, 0);
  473.     temp[0]=x;
  474.     temp[1]=y;
  475.     temp[2]=x+w-1;
  476.     temp[3]=y+h-1;
  477.     v_bar(v_handle, temp);           /* blank the interior */
  478.     vsf_interior(v_handle, in);
  479.     vsf_style(v_handle, sty);
  480.     vsf_color(v_handle, col);
  481.     v_ellipse(v_handle, x+w/2, y+h/2, w/2, h/2);
  482. }
  483. /****************************************************************/
  484. /*  user closed a window            */
  485. /***************************************************************/
  486. user_close()
  487. {
  488.     int i, x, y, w, h, wh;
  489.     wind_get(i, WF_TOP, &wh, &y, &w, &h);
  490.     i=wi_geti(wh);
  491.     debug_alert("user_close", "CLOSE WINDOW/UPDATE MENU", i+1);
  492.     if(wi_nbr)
  493.         close_window(wh);
  494.     if(wi_nbr < WI_MAX)
  495.         menu_ienable(menutree, OPEN_E, TRUE);
  496.     if(!wi_nbr) 
  497.         menu_ienable(menutree, CLOSE_E, FALSE);
  498. }
  499. /****************************************************************/
  500. /*   Set Window Interior Style       */
  501. /****************************************************************/
  502. set_inter(st)
  503. int st;
  504. {
  505.     int i, j, x, y, w, h, wh;
  506.     wind_get(i, WF_TOP, &wh, &y, &w, &h);
  507.     i=wi_geti(wh);
  508.     if(wh == 0) return;        /* no windows open */
  509.     debug_alert("set_inter", "SET INTERIOR STYLE/OPTION MENU", i+1);
  510.     wi_c[i].inter=st;
  511.     menutree[DOTFIL_E].ob_state &= ~CHECKED;    /* remove checks from  */
  512.     menutree[SOLFIL_E].ob_state &= ~CHECKED;    /* interior option menu  */
  513.     menutree[CRSFIL_E].ob_state &= ~CHECKED;
  514.     switch(st) {                                /* now check interior */
  515.         case 1:                                    /* passed as a argument */
  516.             menutree[SOLFIL_E].ob_state |= CHECKED;
  517.             break;
  518.         case 2:
  519.             menutree[DOTFIL_E].ob_state |= CHECKED;
  520.             break;
  521.         case 3:
  522.             menutree[CRSFIL_E].ob_state |= CHECKED;
  523.             break;
  524.     }
  525.     j=1000/style_max(i);                        /* calc size of slider */
  526.     wind_set(wh, 16, j, y, w, h);                /* set size of slider */
  527.     j=1000*(wi_c[i].style-1)/(style_max(i)-1);    /* calc pos. of slider */
  528.     wind_set(wh, WF_VSLIDE, j, y, w, h);        /* set pos. of slider */
  529. }
  530. /****************************************************************/
  531. /*   Get Maximum Style Index Value for Top Window    */
  532. /****************************************************************/
  533. style_max(i)
  534. int i;
  535. {
  536.     switch(wi_c[i].inter) {
  537.         case 1: return(1);
  538.         case 2: return(24);
  539.         case 3: return(12);
  540.     }
  541.     return(0);
  542. }
  543. /****************************************************************/
  544. /*   Update Window Information in the Dialog Box */
  545. /****************************************************************/
  546. up_winfo()
  547. {        /* an example of modifying text objects */
  548.     int x, y, w, h, i, wh;
  549.     OBJECT *ta;
  550.     wind_get(i, WF_TOP, &wh, &y, &w, &h);
  551.     i=wi_geti(wh);
  552.     debug_alert("up_winfo", "UPDATE WIND INFO IN DIALOG BOX", i+1);
  553.     wind_get(wh, WF_CURRXYWH, &x, &y, &w, &h);
  554.     if(!rsrc_gaddr(R_TREE, WINFO_T, &ta)) return;
  555.     itoa(i+1, ((TEDINFO *)ta[WINDNB_O].ob_spec)->te_ptext, 1);
  556.     itoa(x, ((TEDINFO *)ta[X_O].ob_spec)->te_ptext, 3);
  557.     itoa(y, ((TEDINFO *)ta[Y_O].ob_spec)->te_ptext, 3);
  558.     itoa(w, ((TEDINFO *)ta[WIDTH_O].ob_spec)->te_ptext, 3);
  559.     itoa(h, ((TEDINFO *)ta[HEIGTH_O].ob_spec)->te_ptext, 3);
  560.     itoa(wi_c[i].color, ((TEDINFO *)ta[COLOR_O].ob_spec)->te_ptext, 3);
  561.     itoa(wi_c[i].style, ((TEDINFO *)ta[STYLE_O].ob_spec)->te_ptext, 2);
  562.     itoa(wi_c[i].inter, ((TEDINFO *)ta[INTER_O].ob_spec)->te_ptext, 1);
  563. }
  564. /****************************************************************/
  565. /*   Process MENU selection          */
  566. /****************************************************************/
  567. proc_menu()
  568. {
  569.     int i, j, x, y ,w, h, wh;
  570.     debug_alert("proc_menu", "PROCESS MENU BAR SELECTION", 0);
  571.     switch(msgbuff[4]) {
  572.         case OPEN_E:
  573.             if(wi_nbr < WI_MAX) {
  574.                 wh=open_window();
  575.                 if(wh < 0) 
  576.                     form_alert(1, TOMANY_WI);
  577.                 else {
  578.                     i=wi_geti(wh);
  579.                     set_inter(wi_c[i].inter);
  580.                     j=1000/512;    /* calc size of slider */
  581.                     wind_set(msgbuff[3], 15, j, y, w, h);/* set size of slider */
  582.                     menu_ienable(menutree, CLOSE_E, TRUE);
  583.                 }
  584.             }
  585.             if(wi_nbr > WI_MAX-1)
  586.                 menu_ienable(menutree, OPEN_E, FALSE);
  587.             break;
  588.         case CLOSE_E:
  589.             user_close();
  590.             break;
  591.         case ABOUT_E:
  592.             simple_dialog(ABOUT_T);
  593.             break;
  594.         case HWIND_E:
  595.             simple_dialog(WINDOW_T);
  596.             break;
  597.         case HARSLD_E:
  598.             simple_dialog(ARSLID_T);
  599.             break;
  600.         case HTRACE_E:
  601.             simple_dialog(TRACE_T);
  602.             break;
  603.         case TRACE_E:
  604.             menutree[TRACE_E].ob_state ^= CHECKED;
  605.             dtrace^=TRUE;
  606.             break;
  607.         case DOTFIL_E:
  608.             set_inter(2);
  609.             re_draw=TRUE;
  610.             break;
  611.         case SOLFIL_E:
  612.             set_inter(1);
  613.             re_draw=TRUE;
  614.             break;
  615.         case CRSFIL_E:
  616.             set_inter(3);
  617.             re_draw=TRUE;
  618.             break;
  619.         case WINFO_E:
  620.             up_winfo();
  621.             simple_dialog(WINFO_T);
  622.             break;
  623.         case QUIT_E:
  624.             terminat=TRUE;
  625.     }
  626.     menu_tnormal(menutree, msgbuff[3]);        /* reset menu title */
  627. }
  628. /****************************************************************/
  629. /*  Process GEM Events                */
  630. /***************************************************************/
  631. proc_events()
  632. {
  633.     int event, init_info, x, y, w, h, i, j, k, wh;
  634.     debug_alert("proc_events", "PROCESS GEM EVENT MESSAGES ", 0);    
  635.     fulled=init_info=FALSE;
  636.     graf_mouse(ARROW,0x0L);        /* set mouse shape    */
  637.     while(terminat == FALSE) {    
  638.         event = evnt_multi(MU_MESAG | MU_BUTTON | MU_KEYBD,
  639.             1,1,butdown,
  640.             0,0,0,0,0,
  641.             0,0,0,0,0,
  642.             msgbuff,0,0,&mx,&my,&j,&j,&keycode,&j);
  643.  
  644.         re_draw=FALSE;
  645.         wind_update(TRUE);
  646.         if (event & MU_MESAG) {
  647.             i=wi_geti(msgbuff[3]);        /* get window control index */
  648.             switch (msgbuff[0]) {
  649.                 case MN_SELECTED:
  650.                     proc_menu();
  651.                     break;
  652.                 case WM_REDRAW:
  653.                     debug_alert("proc_events", "REDRAW EVENT", i+1); 
  654.                     do_redraw(msgbuff[3],msgbuff[4],msgbuff[5],msgbuff[6],
  655.                         msgbuff[7]);
  656.                     break;
  657.                   case WM_NEWTOP:
  658.                   case WM_TOPPED:
  659.                       debug_alert("proc_events", "NEW/TOPPED EVENT", i+1);
  660.                     wind_set(msgbuff[3],WF_TOP,0,0,0,0);
  661.                     set_inter(wi_c[i].inter);
  662.                     break;
  663.                   case WM_SIZED:
  664.                   case WM_MOVED:
  665.                       debug_alert("proc_events", "MOVED/SIZED EVENT", i+1);
  666.                       fulled = FALSE;
  667.                     if(msgbuff[6]<MIN_WIDTH)msgbuff[6]=MIN_WIDTH;
  668.                     if(msgbuff[7]<MIN_HEIGHT)msgbuff[7]=MIN_HEIGHT;
  669.                     wind_set(msgbuff[3],WF_CURRXYWH,msgbuff[4],msgbuff[5],
  670.                         msgbuff[6],msgbuff[7]);
  671.                     disp_loc(msgbuff[3], msgbuff[4], msgbuff[5]);
  672.                     wind_set(msgbuff[3], WF_NAME, wi_c[i].name, 0, 0);
  673.                     if(wind_smaller(msgbuff[3])) {
  674.                         re_draw=TRUE;
  675.                     }
  676.                     break;
  677.                   case WM_FULLED:
  678.                       debug_alert("proc_events", "FULLED EVENT", i+1);
  679.                     if(fulled) {    /* the window is fulled, revert to */
  680.                                     /* previous size */
  681.                         wind_get(msgbuff[3], WF_PREVXYWH, &x, &y, &w, &h);
  682.                         wind_set(msgbuff[3],WF_CURRXYWH, x, y, w, h);
  683.                         disp_loc(msgbuff[3], x, y);
  684.                             /* this check is necessary because GEM */
  685.                             /* doesn't send a redraw event when the */
  686.                             /* previous X & Y is the upper left corner */
  687.                             /* of the screen */
  688.                         if(wind_smaller(msgbuff[3]))
  689.                             if(x == 0 && y < 20)
  690.                                 re_draw=TRUE;
  691.                     }
  692.                     else {            /* the window is not fulled, make */
  693.                                     /* full size of desktop */
  694.                         wind_set(msgbuff[3],WF_CURRXYWH, xdesk, ydesk, 
  695.                             wdesk, hdesk);
  696.                         disp_loc(msgbuff[3], xdesk, ydesk);
  697.                     }
  698.                     wind_set(msgbuff[3], WF_NAME, wi_c[i].name, 0, 0);
  699.                     fulled ^= TRUE;
  700.                     break;
  701.                 case WM_ARROWED:
  702.                     if(msgbuff[4] > 3) {    /* horizontal arrows */
  703.                         debug_alert("proc_events", "HORIZ. ARROW EVENT", i+1);
  704.                         if(msgbuff[4] == 4 || msgbuff[4] == 6)
  705.                             wi_c[i].color--;
  706.                         if(msgbuff[4] == 5 || msgbuff[4] == 7)
  707.                             wi_c[i].color++;
  708.                         Setcolor(i+1, wi_c[i].color);
  709.                         j=1000l*wi_c[i].color/512l;
  710.                         wind_set(msgbuff[3], WF_HSLIDE, j, y, w, h);
  711.                     }
  712.                     else {                    /* vertical arrows */
  713.                         debug_alert("proc_events", "VERT. ARROW EVENT", i+1);
  714.                         if(msgbuff[4] == 3 || msgbuff[4] == 1) 
  715.                             wi_c[i].style++;
  716.                         if(msgbuff[4] == 2 || msgbuff[4] == 0) 
  717.                             wi_c[i].style--;
  718.                         j=wi_c[i].style;
  719.                         if(j < 1)
  720.                             wi_c[i].style=1;
  721.                         if(j > style_max(i))
  722.                             wi_c[i].style=style_max(i);
  723.                             /* calc pos. of slider */
  724.                         j=1000*(wi_c[i].style-1)/(style_max(i)-1);
  725.                             /* set pos. of slider */
  726.                         wind_set(msgbuff[3], WF_VSLIDE, j, y, w, h);
  727.                         re_draw=TRUE;
  728.                     }
  729.                     break;
  730.                 case WM_VSLID:
  731.                     debug_alert("proc_events", "VERT. SLIDER EVENT", i+1);
  732.                         /* calc style value from slider pos */
  733.                     wi_c[i].style=(msgbuff[4]*style_max(i))/1000;
  734.                         /* set slider to new pos */
  735.                     wind_set(msgbuff[3], WF_VSLIDE, msgbuff[4], y, w, h);
  736.                     re_draw=TRUE;
  737.                     break;
  738.                 case WM_HSLID:
  739.                     debug_alert("proc_events", "HORIZ. SLIDER EVENT", i+1);
  740.                     j=(msgbuff[4]*512l)/1000l;
  741.                     Setcolor(i+1, j);
  742.                     wi_c[i].color=j;
  743.                     wind_set(msgbuff[3], WF_HSLIDE, msgbuff[4], y, w, h);
  744.                     break;
  745.                 case WM_CLOSED:
  746.                     debug_alert("proc_events", "WINDOW CLOSE EVENT", i+1);
  747.                     user_close();
  748.                     break;
  749.               }
  750.           }
  751.         if(re_draw == TRUE) {
  752.             wind_get(i, WF_TOP, &wh, &y, &w, &h);
  753.             wind_get(wh, WF_CURRXYWH, &x, &y, &w, &h);
  754.             do_redraw(wh, x, y, w, h);
  755.         }
  756.         wind_update(FALSE);
  757.         
  758.             /* This could not be done in MAIN because the mouse pointer */
  759.             /* stayed busy until after the dialog box was clicked */
  760.             /* I believe this is caused by the initial redraw event that */
  761.             /* GEM sends for a non-existent window */
  762.         if(init_info == FALSE) {
  763.             simple_dialog(ABOUT_T);        /* show openning dialog box */
  764.             init_info=TRUE;
  765.         }
  766.     }
  767. }
  768.